﻿using System;
using System.Configuration.Abstractions;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using SimpleInjector;
using Sustainalytics.Auth.Service.OAuth;
using Sustainalytics.Claims;
using Sustainalytics.ClientDW.Entities.Universes;
using Sustainalytics.MongoDB.Extensions;

namespace Sustainalytics.Auth.Service
{
    [DebuggerStepThrough]
    [ExcludeFromCodeCoverage]
    public static class SimpleInjectorConfig
    {
        public static Container Register()
        {
            var container = new Container();

            container.Register();
            container.Verify();

            return container;
        }

        private static void Register(this Container container)
        {
            ConfigurationManager.RegisterTypeConverters(new TimeSpanConverter());
            container.Register<IAppSettings>(() => ConfigurationManager.Instance.AppSettings);
            container.Register<IOperationClaimsRetriever>(() => new OperationClaimsRetriever(), Lifestyle.Singleton);

            container.RegisterCollections();
        }

        private static void RegisterCollections(this Container container)
        {
            // register collections for GA
            container.Register(() => MongoFactory.GetCollectionFromClientPlatform<Entities.User>());
            container.Register(() => MongoFactory.GetCollectionFromClientPlatform<Entities.ClientUser>());
            container.Register(() => MongoFactory.GetCollectionFromClientPlatform<Entities.Account>());
            container.Register(() => MongoFactory.GetCollectionFromClientPlatform<RefreshToken>());
            container.Register(() => MongoFactory.GetCollectionFromDatabase<FeatureUniverse>(db => db.ClientUniverses));
        }

        public class TimeSpanConverter : IConvertType
        {
            public Type TargetType => typeof(TimeSpan);

            public object Convert(string configurationValue)
            {
                TimeSpan timeSpan;

                if (!TimeSpan.TryParse(configurationValue, out timeSpan))
                    throw new System.Configuration.ConfigurationErrorsException($"The value '{configurationValue}' from appSettings is not a valid TimeSpan");

                return timeSpan;
            }
        }
    }
}
